package arffreader;

/**
 *
 */
public class QLearner {
    private double[][] qTable = null;
    
    private double[][] tuplas = null;

    /**
     * Constructor
     * @param t conjunto de tuplas
     */
    QLearner(double[][] t) {
        this.tuplas = new double[t.length][t[0].length];
        for(int i = 0;i<t.length;i++){
            for(int j = 0; j< t[0].length;j++){
                this.tuplas[i][j] = t[i][j];
            }
        }
    }
    
    public void qLearning(int nestados, int nacciones, double ciclos, double alfa, double gamma){
        qTable = new double[nestados][nacciones];
        /**
         * Inicializar la tabla q
         */
        for(int i = 0; i<nestados;i++){
            for(int j = 0; j<nacciones;j++){
                qTable[i][j] = 0;
            }
        }
        /**
         * Aprender la tabla q
         */
        for (int ciclo = 0; ciclo < ciclos; ciclo++) {
            int ntuplas = tuplas.length;
            for (int i = 0; i < ntuplas; i++) {
                actualizaQ(tuplas[i][0],/*estado*/
                        tuplas[i][1],/*accion*/
                        tuplas[i][2],/*siguiente*/
                        tuplas[i][3],/*refuerzo*/
                        alfa,
                        gamma,
                        nacciones);
            }
        }
    }

    private void actualizaQ(double estado, double accion, double siguiente, double refuerzo, double alfa, double gamma, int nacciones) {
        double maxSiguiente = maxQ(siguiente, nacciones);
        
        qTable[(int)estado][(int)accion] = ((1 - alfa) * qTable[(int)estado][(int)accion]) +
                                               (alfa * (refuerzo + (gamma * maxSiguiente)));
    }

    private double maxQ(double siguiente, int nacciones) {
        double max = 0;
        for (int i = 0; i<nacciones; i++){
           if(qTable[(int)siguiente][i] > max){
               max = qTable[(int)siguiente][i];
           } 
        }
        return max;
    }
    
    public double[][] getQTable(){
        return qTable;
    }
}
